package com.example.wificontroller3;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class CrossPadView extends View {

    private int padSize;
    private Bitmap centerBitmap;
    private Bitmap upBitmap;
    private Bitmap downBitmap;
    private Bitmap leftBitmap;
    private Bitmap rightBitmap;
    private Bitmap upRightBitmap;
    private Bitmap downRightBitmap;
    private Bitmap upLeftBitmap;
    private Bitmap downLeftBitmap;
    private Direction dir = Direction.DIRECTION_CENTER;
    private Rect upRect;
    private Rect downRect;
    private Rect leftRect;
    private Rect rightRect;
    private Rect upRightRect;
    private Rect downRightRect;
    private Rect upLeftRect;
    private Rect downLeftRect;
    private float proportion1;
    private float proportion2;
    private DirChangedListener dirChangedListener;
    private Paint paint;

    public CrossPadView(Context context) {
        super(context);
    }

    public CrossPadView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //第二个参数就是我们在styles.xml文件中的<declare-styleable>标签
        //即属性集合的标签，在R文件中名称为R.styleable+name
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CrossPadView);

        //第一个参数为属性集合里面的属性，R文件名称：R.styleable+属性集合名称+下划线+属性名称
        //第二个参数为，如果没有设置这个属性，则设置的默认的值
        padSize = a.getDimensionPixelSize(R.styleable.CrossPadView_default_size, 100);
        Drawable tempBitmap = a.getDrawable(R.styleable.CrossPadView_padBitmap);
        centerBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_upBitmap);
        upBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_downBitmap);
        downBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_leftBitmap);
        leftBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_rightBitmap);
        rightBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_upRightBitmap);
        upRightBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_downRightBitmap);
        downRightBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_upLeftBitmap);
        upLeftBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        tempBitmap = a.getDrawable(R.styleable.CrossPadView_downLeftBitmap);
        downLeftBitmap = ((BitmapDrawable) tempBitmap).getBitmap();
        //按键在图片中所在区域在大图片中所占的比例
        proportion1 = a.getFloat(R.styleable.CrossPadView_proportion1, 0.36f);
        proportion2 = a.getFloat(R.styleable.CrossPadView_proportion2, 0.63f);

        //最后记得将TypedArray对象回收
        a.recycle();
        paint = new Paint();
    }

    /**
     * 方向
     */
    public enum Direction {
        DIRECTION_LEFT, // 左
        DIRECTION_RIGHT, // 右
        DIRECTION_UP, // 上
        DIRECTION_DOWN, // 下
        DIRECTION_UP_LEFT, // 左上
        DIRECTION_UP_RIGHT, // 右上
        DIRECTION_DOWN_LEFT, // 左下
        DIRECTION_DOWN_RIGHT, // 右下
        DIRECTION_CENTER // 中间
    }

    private void initSize(int widthMeasureSpec, int heightMeasureSpec){
        //最终计算后的方向键尺寸
        int width = padSize;
        int height = padSize;
        //系统计算使用的尺寸
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int specWidth = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int specHeight = MeasureSpec.getSize(heightMeasureSpec);

        switch (widthMode) {
            case MeasureSpec.UNSPECIFIED: {//如果没有指定大小，就设置为默认大小
                width = padSize;
                break;
            }
            case MeasureSpec.AT_MOST:
            case MeasureSpec.EXACTLY: {//如果测量模式是最大取值为size
                //我们将大小取最大值,你也可以取其他值
                width = specWidth;
                break;
            }//如果是固定的大小，那就不要去改变它
        }

        switch (heightMode) {
            case MeasureSpec.UNSPECIFIED: {//如果没有指定大小，就设置为默认大小
                height = padSize;
                break;
            }
            case MeasureSpec.AT_MOST:
            case MeasureSpec.EXACTLY: {//如果测量模式是最大取值为size
                //我们将大小取最大值,你也可以取其他值
                height = specHeight;
                break;
            }//如果是固定的大小，那就不要去改变它
        }

        padSize = Math.max(width, height);

        //根据四个方向键在图片中所占区域的比例计算四个方向键所在的矩形区域
        int x1 = (int)(padSize * proportion1);
        int x2 = (int)(padSize * proportion2);
        int y1 = (int)(padSize * proportion1);
        int y2 = (int)(padSize * proportion2);
        upRect = new Rect(x1, 0, x2, y1);
        downRect = new Rect(x1, y2, x2, padSize);
        leftRect = new Rect(0, y1, x1, y2);
        rightRect = new Rect(x2, y1, padSize, y2);

        upRightRect = new Rect(x2, 0, padSize, y1);
        downRightRect = new Rect(x2, y2, padSize, padSize);
        upLeftRect = new Rect(0, 0, x1, y1);
        downLeftRect = new Rect(0, y2, x1, padSize);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        initSize(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(padSize, padSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getMeasuredWidth();//也可以是getMeasuredHeight()/2,本例中我们已经将宽高设置相等了

        //开始绘制
        Rect src = new Rect(0, 0, centerBitmap.getWidth(), centerBitmap.getHeight());
        Rect dst = new Rect(0, 0, width, width);
        switch(dir){
            case DIRECTION_CENTER:
                canvas.drawBitmap(centerBitmap, src, dst, paint);
                break;
            case DIRECTION_UP:
                canvas.drawBitmap(upBitmap, src, dst, paint);
                break;
            case DIRECTION_DOWN:
                canvas.drawBitmap(downBitmap, src, dst, paint);
                break;
            case DIRECTION_LEFT:
                canvas.drawBitmap(leftBitmap, src, dst, paint);
                break;
            case DIRECTION_RIGHT:
                canvas.drawBitmap(rightBitmap, src, dst, paint);
                break;
            case DIRECTION_UP_RIGHT:
                canvas.drawBitmap(upRightBitmap, src, dst, paint);
                break;
            case DIRECTION_DOWN_RIGHT:
                canvas.drawBitmap(downRightBitmap, src, dst, paint);
                break;
            case DIRECTION_UP_LEFT:
                canvas.drawBitmap(upLeftBitmap, src, dst, paint);
                break;
            case DIRECTION_DOWN_LEFT:
                canvas.drawBitmap(downLeftBitmap, src, dst, paint);
                break;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:// 按下
            case MotionEvent.ACTION_MOVE:// 移动
                float moveX = event.getX();
                float moveY = event.getY();
                if(upRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_UP;
                }else if (downRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_DOWN;
                }else if (leftRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_LEFT;
                }else if (rightRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_RIGHT;
                }else if (upRightRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_UP_RIGHT;
                }else if (downRightRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_DOWN_RIGHT;
                }else if (upLeftRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_UP_LEFT;
                }else if (downLeftRect.contains((int)moveX, (int)moveY)){
                    dir = Direction.DIRECTION_DOWN_LEFT;
                }
                break;
            case MotionEvent.ACTION_UP:// 抬起
                dir = Direction.DIRECTION_CENTER;
                break;
            case MotionEvent.ACTION_CANCEL:// 移出区域
                float upX = event.getX();
                float upY = event.getY();
                break;
        }
        dirChangedListener.dirChanged(dir);
        invalidate(); //重绘手柄
        return true;
    }

    public void setOnDirChangedListener(DirChangedListener dirChangedListener){
        this.dirChangedListener = dirChangedListener;
        dirChangedListener.dirChanged(dir);
    }

    interface DirChangedListener{
        void dirChanged(Direction dir);
    }
}
